#!/usr/bin/env python3

"""
Example HTTP client for Java Decompiler HTTP Server
Demonstrates how to use the REST API endpoints from Python
"""

import requests
import json
import sys
from typing import Optional, Dict, Any, List

class JavaDecompilerClient:
    def __init__(self, base_url: str = "http://localhost:3000"):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({'Content-Type': 'application/json'})
        self.session.timeout = 60
    
    def health_check(self) -> Dict[str, Any]:
        """Check if the server is running"""
        try:
            response = self.session.get(f"{self.base_url}/health")
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Health check failed: {e}")
    
    def get_api_info(self) -> Dict[str, Any]:
        """Get API information and available endpoints"""
        try:
            response = self.session.get(f"{self.base_url}/api/info")
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"API info failed: {e}")
    
    def search_artifacts(self, query: str) -> Dict[str, Any]:
        """Search for Maven artifacts"""
        try:
            response = self.session.post(f"{self.base_url}/api/search-artifacts", 
                                       json={"query": query})
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Search artifacts failed: {e}")
    
    def download_artifact(self, group_id: str, artifact_id: str, version: str, 
                         packaging: str = "jar") -> Dict[str, Any]:
        """Download and analyze a Maven artifact"""
        try:
            response = self.session.post(f"{self.base_url}/api/download-artifact", 
                                       json={
                                           "groupId": group_id,
                                           "artifactId": artifact_id,
                                           "version": version,
                                           "packaging": packaging
                                       })
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Download artifact failed: {e}")
    
    def search_classes(self, query: str, artifact_id: Optional[str] = None) -> Dict[str, Any]:
        """Search for classes in downloaded artifacts"""
        try:
            data = {"query": query}
            if artifact_id:
                data["artifactId"] = artifact_id
            
            response = self.session.post(f"{self.base_url}/api/search-classes", json=data)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Search classes failed: {e}")
    
    def decompile_class(self, group_id: str, artifact_id: str, version: str, 
                       class_name: str) -> Dict[str, Any]:
        """Decompile a specific Java class"""
        try:
            response = self.session.post(f"{self.base_url}/api/decompile-class", 
                                       json={
                                           "groupId": group_id,
                                           "artifactId": artifact_id,
                                           "version": version,
                                           "className": class_name
                                       })
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Decompile class failed: {e}")
    
    def get_versions(self, group_id: str, artifact_id: str) -> Dict[str, Any]:
        """Get available versions for a Maven artifact"""
        try:
            response = self.session.post(f"{self.base_url}/api/get-versions", 
                                       json={
                                           "groupId": group_id,
                                           "artifactId": artifact_id
                                       })
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Get versions failed: {e}")
    
    def scan_project(self, project_path: str) -> Dict[str, Any]:
        """Scan a local Java project"""
        try:
            response = self.session.post(f"{self.base_url}/api/scan-project", 
                                       json={"projectPath": project_path})
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Scan project failed: {e}")
    
    def search_local_repository(self, query: str) -> Dict[str, Any]:
        """Search local Maven repository"""
        try:
            response = self.session.post(f"{self.base_url}/api/search-local-repository", 
                                       json={"query": query})
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Search local repository failed: {e}")
    
    def find_class_in_local_repository(self, class_name: str, 
                                     repository_path: Optional[str] = None) -> Dict[str, Any]:
        """Find and decompile a class from local Maven repository"""
        try:
            data = {"className": class_name}
            if repository_path:
                data["repositoryPath"] = repository_path
            
            response = self.session.post(f"{self.base_url}/api/find-class-local", json=data)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise Exception(f"Find class in local repository failed: {e}")


def run_examples():
    """Run example usage of the Java Decompiler HTTP API"""
    client = JavaDecompilerClient()
    
    try:
        print("🔍 Testing Java Decompiler HTTP API...\n")
        
        # Health check
        print("1. Health Check:")
        health = client.health_check()
        print(f"   Status: {health['status']}")
        print(f"   Timestamp: {health['timestamp']}")
        print()
        
        # API info
        print("2. API Info:")
        info = client.get_api_info()
        print(f"   Name: {info['name']}")
        print(f"   Version: {info['version']}")
        print(f"   Available endpoints: {len(info['endpoints'])}")
        print()
        
        # Search artifacts
        print("3. Search Artifacts (spring-boot-starter):")
        artifacts = client.search_artifacts('spring-boot-starter')
        print(f"   Found {artifacts['found']} artifacts")
        if artifacts['artifacts']:
            print(f"   First artifact: {artifacts['artifacts'][0]}")
        print()
        
        # Download specific artifact
        print("4. Download Artifact (commons-lang3):")
        download = client.download_artifact(
            'org.apache.commons',
            'commons-lang3', 
            '3.12.0'
        )
        if download['success']:
            print(f"   Downloaded successfully! Found {download['classCount']} classes")
            class_names = [c['fullName'] for c in download['classes'][:3]]
            print(f"   First few classes: {class_names}")
        print()
        
        # Search classes in downloaded artifact
        print("5. Search Classes (StringUtils):")
        classes = client.search_classes('StringUtils')
        if classes['totalMatches'] > 0:
            print(f"   Found {classes['totalMatches']} matching classes")
            first_match = classes['matches'][0]
            print(f"   First match: {first_match}")
            
            # Decompile the first match
            print("\n6. Decompile Class:")
            decompiled = client.decompile_class(
                first_match['artifact']['groupId'],
                first_match['artifact']['artifactId'],
                first_match['artifact']['version'],
                first_match['fullName']
            )
            
            if decompiled['success']:
                print(f"   Decompiled {decompiled['className']} successfully!")
                print(f"   Source length: {len(decompiled['source'])} characters")
                print("   First 200 characters:")
                print(f"   {decompiled['source'][:200]}...")
        print()
        
        # Get versions
        print("7. Get Versions (commons-lang3):")
        versions = client.get_versions('org.apache.commons', 'commons-lang3')
        print(f"   Found {len(versions['versions'])} versions")
        print(f"   Latest versions: {versions['versions'][:5]}")
        print()
        
        # Search local repository
        print("8. Search Local Repository (commons):")
        local_search = client.search_local_repository('commons')
        print(f"   Found {local_search['found']} local artifacts")
        if local_search['artifacts']:
            print(f"   First local artifact: {local_search['artifacts'][0]}")
        print()
        
        print("✅ All examples completed successfully!")
        
    except Exception as error:
        print(f"❌ Error running examples: {error}")
        
        # Check if server is running
        try:
            client.health_check()
        except:
            print("\n💡 Make sure the HTTP server is running:")
            print("   npm run dev:http")
            print("   # or")
            print("   npm run build && npm run start:http")


if __name__ == "__main__":
    # Command line usage
    if len(sys.argv) > 1:
        client = JavaDecompilerClient()
        command = sys.argv[1]
        
        try:
            if command == "health":
                result = client.health_check()
                print(json.dumps(result, indent=2))
            
            elif command == "search" and len(sys.argv) > 2:
                query = sys.argv[2]
                result = client.search_artifacts(query)
                print(json.dumps(result, indent=2))
            
            elif command == "download" and len(sys.argv) > 4:
                group_id, artifact_id, version = sys.argv[2:5]
                result = client.download_artifact(group_id, artifact_id, version)
                print(json.dumps(result, indent=2))
            
            elif command == "decompile" and len(sys.argv) > 5:
                group_id, artifact_id, version, class_name = sys.argv[2:6]
                result = client.decompile_class(group_id, artifact_id, version, class_name)
                print(json.dumps(result, indent=2))
            
            else:
                print("Usage:")
                print("  python http-client-example.py health")
                print("  python http-client-example.py search <query>")
                print("  python http-client-example.py download <groupId> <artifactId> <version>")
                print("  python http-client-example.py decompile <groupId> <artifactId> <version> <className>")
                print("  python http-client-example.py  # run examples")
        
        except Exception as e:
            print(f"Error: {e}")
            sys.exit(1)
    else:
        # Run examples
        run_examples()